SPDX-FileCopyrightText: 2019 Arnaud Froment & Thomas Paquot SPDX-FileCopyrightText: 2024 AlICe laboratory https://alicelab.be
SPDX-License-Identifier: GPL-3.0-or-later
-- coding:Utf8 --
Imaginary Landscape Nr.4 - John Cage # Authors: Arnaud Froment & Thomas Paquot # Date: 24/01/2020 # Blender version: 2.80 # OS: MacOS Catalina & Windows 10 #
import of the external functions
import bpy
import random
from math import piactivation of boolean tools in blender settings
import addon_utils
addon_utils.enable("object_boolean_tools")delete neg cube at every run
def reset():
bpy.ops.object.select_all(action="DESELECT")
bpy.data.objects["negative"].select_set(True)
bpy.ops.object.delete()
PARAMETERS = {"scale_min": 10, "scale_max": 25, "patterns": 6, "radios": 12}
COIN_TOSSES = {"heads": 0, "tails": 0}
OBJECTS = {
"cubes": [0, 0],
"tetrahedrons": [0, 0],
"icosahedrons": [0, 0],
} # index 0 = build; index 1 = unbuildCoin toss 3 times print(“You flipped heads”, total_heads, “times”,”and tails”, total_tails, “times”)
def cointoss():
total_heads = 0
total_tails = 0
for _ in range(3): # Coin toss 3 times to create a line 0 or 1 see futher down
coin = random.randint(1, 2)
if coin == 1: # heads
total_heads += 1
elif coin == 2: # tails
total_tails += 1 if (total_heads == 3 and total_tails == 0) or (
total_heads == 2 and total_tails == 1
):
hexlist.append(0) # adds a 0 to hexlist
print("🀰🀰🀰🀰 🀰🀰🀰🀰") # Line print if 0
elif (total_heads == 1 and total_tails == 2) or (
total_heads == 0 and total_tails == 3
):
hexlist.append(1) # adds a 1 to hexlist
print("🀰🀰🀰🀰🀰🀰🀰🀰🀰🀰🀰🀰") # line print if 1
COIN_TOSSES["heads"] += total_heads
COIN_TOSSES["tails"] += total_tailsempty hexagram
hexlist = []clear the hexagram and load it again
def hexagram():
hexlist.clear()
for _ in range(6): # 6 x 3 coin tosses for an hexagram to be created
cointoss()print(hexlist,’\n’)
print()iChing List of 64 Hexagrams
ichinglist = [
[1, 1, 1, 1, 1, 1],
[0, 0, 0, 0, 0, 0],
[0, 1, 0, 0, 0, 1],
[1, 0, 0, 0, 1, 0],
[0, 1, 0, 1, 1, 1],
[1, 1, 1, 0, 1, 0],
[0, 0, 0, 0, 1, 0],
[0, 1, 0, 0, 0, 0],
[1, 1, 0, 1, 1, 1],
[1, 1, 1, 0, 1, 1],
[0, 0, 0, 1, 1, 1],
[1, 1, 1, 0, 0, 0],
[1, 1, 1, 1, 0, 1],
[1, 0, 1, 1, 1, 1],
[0, 0, 0, 1, 0, 0],
[0, 0, 1, 0, 0, 0],
[0, 1, 1, 0, 0, 1],
[1, 0, 0, 1, 1, 0],
[0, 0, 0, 0, 1, 1],
[1, 1, 0, 0, 0, 0],
[1, 0, 1, 0, 0, 1],
[1, 0, 0, 1, 0, 1],
[1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 1],
[1, 1, 1, 0, 0, 1],
[1, 0, 0, 1, 1, 1],
[1, 0, 0, 0, 0, 1],
[0, 1, 1, 1, 1, 0],
[0, 1, 0, 0, 1, 0],
[1, 0, 1, 1, 0, 1],
[0, 1, 1, 1, 0, 0],
[0, 0, 1, 1, 1, 0],
[1, 1, 1, 1, 0, 0],
[0, 0, 1, 1, 1, 1],
[0, 0, 0, 1, 0, 1],
[1, 0, 1, 0, 0, 0],
[1, 1, 0, 1, 0, 1],
[1, 0, 1, 0, 1, 1],
[0, 1, 0, 1, 0, 0],
[0, 0, 1, 0, 1, 0],
[1, 0, 0, 0, 1, 1],
[1, 1, 0, 0, 0, 1],
[0, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 0],
[0, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 0],
[0, 1, 1, 0, 1, 0],
[0, 1, 0, 1, 1, 0],
[0, 1, 1, 1, 0, 1],
[1, 0, 1, 1, 1, 0],
[0, 0, 1, 0, 0, 1],
[1, 0, 0, 1, 0, 0],
[1, 1, 0, 1, 0, 0],
[0, 0, 1, 0, 1, 1],
[0, 0, 1, 1, 0, 1],
[1, 0, 1, 1, 0, 0],
[1, 1, 0, 1, 1, 0],
[0, 1, 1, 0, 1, 1],
[1, 1, 0, 0, 1, 0],
[0, 1, 0, 0, 1, 1],
[1, 1, 0, 0, 1, 1],
[0, 0, 1, 1, 0, 0],
[0, 1, 0, 1, 0, 1],
[1, 0, 1, 0, 1, 0],
]Defines the parameters (64 values per parameters = I CHING) at each structural point (random)
def make_random():
hexagram()
x = (
ichinglist.index(hexlist) + 1
) # Duration X, #indexing where in the list + 1 the hexagram is situated to randomize a number
hexagram()
y = ichinglist.index(hexlist) + 1 # Dynamic Y
hexagram()
z = ichinglist.index(hexlist) + 1 # Frequency Z
hexagram()
s = ichinglist.index(hexlist) + 1 # Scale
hexagram()
r = (
ichinglist.index(hexlist) + 1
) * 5.625 # Rotation, #5.625 is the amount of times 64 can fit in 360print(x,y,z,s,r)
axis = random.choice(["x", "y", "z"])
if eval(axis) % 2 != 0: # Uneven elements are 0
if axis == "x":
x = 0
elif axis == "y":
y = 0
elif axis == "z":
z = 0
if s not in range(
PARAMETERS["scale_min"], PARAMETERS["scale_max"]
): # Choose a range in the 64 elements
s = 0
return x, y, z, s, r # Giving the info back to the make_random function when calleddefine the keywords of the basic forms
addcube = bpy.ops.mesh.primitive_cube_add
addtetrahedron = bpy.ops.mesh.primitive_cone_add
addicosahedron = bpy.ops.mesh.primitive_ico_sphere_addDefine the pattern
def pattern(loop): # builds objects if no 0 in iching
for _ in range(loop):
x, y, z, s, r = (
make_random()
) ##section for the cube, 8 vertices #return the x y z s r values
if 0 not in {x, y, z, s, r}: # if value is 0
addcube(
size=s,
location=(x, y, z),
rotation=((r * pi / 180), (r * pi / 180), (r * pi / 180)),
)
OBJECTS["cubes"][0] += 1
else:
pass # counter
OBJECTS["cubes"][1] += 1
x, y, z, s, r = make_random() # section for the tetrahedron, 4 vertices
if 0 not in {x, y, z, s, r}:
addtetrahedron(
radius1=s,
radius2=0,
depth=s * 2,
vertices=3,
location=(x, y, z),
rotation=((r * pi / 180), (r * pi / 180), (r * pi / 180)),
)
OBJECTS["tetrahedrons"][0] += 1
else:
pass
OBJECTS["tetrahedrons"][1] += 1
x, y, z, s, r = make_random() # section for the icosahedron, 12 vertices
if 0 not in {x, y, z, s, r}:
addicosahedron(
subdivisions=1,
radius=s,
location=(x, y, z),
rotation=((r * pi / 180), (r * pi / 180), (r * pi / 180)),
)
OBJECTS["icosahedrons"][0] += 1
else:
pass
OBJECTS["icosahedrons"][1] += 1how much radios are chosen
def radio(loop):
for _ in range(loop):
pattern(PARAMETERS["patterns"])call a new score
def score():
radio(PARAMETERS["radios"])shows info of the score created
def scoreinfo():
print("Total coin tosses:", COIN_TOSSES["heads"] + COIN_TOSSES["tails"])
print()
print("Total build cubes:", OBJECTS["cubes"][0])
print("Total unbuild cubes:", OBJECTS["cubes"][1])
print()
print("Total build tetrahedrons:", OBJECTS["tetrahedrons"][0])
print("Total unbuild tetrahedrons:", OBJECTS["tetrahedrons"][1])
print()
print("Total build icosahedrons:", OBJECTS["icosahedrons"][0])
print("Total unbuild icosahedrons:", OBJECTS["icosahedrons"][1])
print()
print("---------------------------")Union off all the events
def union():
bpy.ops.object.select_all(action="SELECT")
bpy.ops.object.booltool_auto_union()Name the Unified object ‘Positive’
def positive():
bpy.ops.object.select_all(action="SELECT")
bpy.context.object.name = "positive"Add the cube of 64 to 64 to create the negative afterwards
def negative():
addcube(size=64, location=(32, 32, 32))
bpy.context.object.name = "negative"
negative = bpy.context.objectBoolean operation: negative(cube) - positive (objects)
def boolnegpos():
bpy.ops.object.modifier_add(type="BOOLEAN")
bpy.context.object.modifiers["Boolean"].operation = "DIFFERENCE"
bpy.context.object.modifiers["Boolean"].object = bpy.data.objects["positive"]
bpy.ops.object.modifier_apply(apply_as="DATA", modifier="Boolean")def delpos():
bpy.ops.object.select_all(action="DESELECT")
bpy.data.objects["positive"].select_set(True)
bpy.ops.object.delete()rescale the final form to a 10x10 square
def rescale():
bpy.ops.object.select_all(action="SELECT")
bpy.ops.transform.resize(value=(0.15625, 0.15625, 0.15625))
bpy.context.object.location[0] = 5
bpy.context.object.location[1] = 5
bpy.context.object.location[2] = 5calling the functions:
reset()
score()
scoreinfo()
union()
positive()
negative()
boolnegpos()
delpos()
rescale()